/* 容斥原理
* 常见问题:
    (1)有n个相同的元素,要求分到m组中,每组至少元素数为1,问有多少种不同的分法？
    C(n-1, m-1)

    (2)允许有些组中分到的元素数为0，也就是组中可以为空的
    首先将每组都填上1个，这样所要元素总数就n+m个，问题也就是转变成将(n+m)个元素分到m组
    C(n+m-1, m-1)
* 本题:
    本题从M个元素分N组
    M+N-1个空隙中插N-1个板子 <=> 方案数C(n+m-1, n-1)
    所有方案数-不满足至少一种条件的方案数(选择数量超了)
    C(m+n+1-(A[1]+1+...超出盒子...+A[j]+1), n-1)
    ->当前盒子j选完，再在其他地方取m-A[j]-1个 = C(n+m-A[j]-2, n-1)
    ->又存在拿到超出盒子的可能，再循环处理
    
*/

#define DEBUG
#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define int long long
const int N = 20, MOD = 1e9+7;
int A[N];
int down = 1; //TLE优化

int qmi(int base, int index, int MOD)
{
    int res = 1;
    while(index)
    {
        if(index & 1) res = (res * base) % MOD;
        base = (base * base) % MOD;
        index >>= 1;
    }
    return res;
}

int C(int a,int b)
{
    if(a < b) return 0;
    int up = 1;
    for(int i = a; i > a-b; --i) up = i %MOD * up % MOD;
    
    return up * qmi(down, MOD-2, MOD)%MOD;
}

signed main()
{
    #ifdef DEBUG
        freopen("./in.txt", "r", stdin);
    #else
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #endif

    int n, m; cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> A[i];
    for(int j = 1; j <= n-1; ++j) down = down * j % MOD;

    int res = 0;
    for(int i = 0; i < 1 << n; i++) {//枚举每种有可能的子集，二进制位表示当前超出A[j]上限
        int a = m + n - 1, b = n - 1; //a: 可分配元素
        int sign = 1; //当前计算的符号位
        for(int j = 0; j < n; j++)
            if(i >> j & 1)//选择j
            {
                sign *= -1;
                a -= A[j] + 1; //当前超出，全部拿完
            }
        res = (res + C(a, b) * sign) % MOD;
    }

    cout << (res+MOD)%MOD << endl;
    
    return 0;
}
